package cn.edu.zjusc.Util;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;

import cn.edu.zjusc.Annotation.*;

public class PersistenceHelper {

	/**
	 * 获得实体列表
	 * 
	 * @param queryString
	 *            HQL语句
	 * @return
	 */
	@SuppressWarnings({ "rawtypes" })
	public static List executeReader(String queryString) {
		return executeReader(queryString, null, null);
	}

	/**
	 * 获得实体列表
	 * 
	 * @param queryString
	 *            HQL语句
	 * @param params
	 *            参数数组
	 * @return
	 */
	@SuppressWarnings({ "rawtypes" })
	public static List executeReader(String queryString, Object[] params) {
		return executeReader(queryString, params, null);
	}

	/**
	 * 获得实体列表
	 * 
	 * @param queryString
	 *            HQL语句
	 * @param params
	 *            参数数组
	 * @param entityClass
	 *            class界定
	 * @return
	 */
	@SuppressWarnings({ "rawtypes" })
	public static List executeReader(String queryString, Object[] params,
			Class<?> entityClass) {

		return executeReader(queryString, params, entityClass, -1, 0);
	}

	/**
	 * 分页获得实体列表
	 * 
	 * @param queryString
	 *            HQL语句
	 * @param params
	 *            参数数组
	 * @param entityClass
	 *            class界定
	 * @param pageIndex
	 *            页号
	 * @param pageSize
	 *            一页数目
	 * @return
	 */
	@SuppressWarnings({ "rawtypes" })
	public static List executeReader(String queryString, Object[] params,
			Class<?> entityClass, int pageIndex, int pageSize) {

		EntityManagerFactory emf = Persistence
				.createEntityManagerFactory("zjusc");
		EntityManager em = emf.createEntityManager();
		Query query;
		if (entityClass != null) {
			query = em.createQuery(queryString, entityClass);
		} else {
			query = em.createQuery(queryString);
		}
		if (params != null) {
			for (int i = 0; i < params.length; i++) {
				Object param = params[i];
				query.setParameter(i + 1, param);
			}
		}
		if (pageIndex != -1) {
			query.setFirstResult((pageIndex - 1) * pageSize).setMaxResults(
					pageSize);
		}

		List resultList = query.getResultList();

		em.close();
		emf.close();

		return resultList;
	}

	/**
	 * 获得单个实体
	 * 
	 * @param queryString
	 *            HQL语句
	 * @return
	 * @throws Exception
	 */
	public static Object getEntity(String queryString) {
		return getEntity(queryString, null, null);
	}

	/**
	 * 获得单个实体
	 * 
	 * @param queryString
	 *            HQL语句
	 * @param params
	 *            参数数组
	 * @return
	 * @throws Exception
	 */
	public static Object getEntity(String queryString, Object[] params) {
		return getEntity(queryString, params, null);
	}

	/**
	 * 获得单个实体
	 * 
	 * @param queryString
	 *            HQL语句
	 * @param params
	 *            参数数组
	 * @param entityClass
	 *            class界定
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings({ "rawtypes" })
	public static Object getEntity(String queryString, Object[] params,
			Class<?> entityClass) {
		List entities = executeReader(queryString, params, entityClass);
		if (entities.size() > 0) {
			return entities.get(0);
		} else {
			Constructor con;
			try {
				con = entityClass.getConstructor();
				return con.newInstance();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				return null;
			}
		}
	}

	/**
	 * 添加实体
	 * 
	 * @param entities
	 */
	public static void addEntity(Object... entities) {
		EntityManagerFactory emf = Persistence
				.createEntityManagerFactory("zjusc");
		EntityManager em = emf.createEntityManager();
		// 开始事务
		em.getTransaction().begin();
		for (Object obj : entities) {
			em.persist(obj);
		}
		// 提交事务
		em.getTransaction().commit();

		em.close();
		emf.close();
	}

	/**
	 * 修改整个实体，更新数据库中所有字段 支持批量
	 * 
	 * @param entities
	 */
	public static void modifyEntity(Object... entities) {
		EntityManagerFactory emf = Persistence
				.createEntityManagerFactory("zjusc");
		EntityManager em = emf.createEntityManager();

		// 开始事务
		em.getTransaction().begin();

		for (Object obj : entities) {
			em.merge(obj);
		}

		// 提交事务
		em.getTransaction().commit();

		em.close();
		emf.close();
	}

	/**
	 * 修改不完全实体
	 * 
	 * @param annotationClass
	 *            标注类
	 * @param conditionEntities
	 */
	public static void modifyPartialEntity(
			Class<? extends Annotation> annotationClass,
			Object... conditionEntities) {
		EntityManagerFactory emf = Persistence
				.createEntityManagerFactory("zjusc");
		EntityManager em = emf.createEntityManager();

		// 开始事务
		em.getTransaction().begin();

		for (Object conditionObj : conditionEntities) {
			Field[] fields = conditionObj.getClass().getDeclaredFields();
			for (Field fl : fields) {
				// 找主键
				if (fl.isAnnotationPresent(Pk.class)) {
					boolean isFieldPrivate = true;
					try {
						if (!fl.isAccessible()) {
							isFieldPrivate = false;
							fl.setAccessible(true);
						}
						Object id = fl.get(conditionObj);
						Object managedObj = em
								.find(conditionObj.getClass(), id);
						PolicySequencer.absorbObject(managedObj, conditionObj,
								annotationClass);
						// 可访问性本来是False
						if (!isFieldPrivate) {
							fl.setAccessible(false);
						}
						break;
					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		}

		// 提交事务
		em.getTransaction().commit();

		em.close();
		emf.close();
	}

	/**
	 * 删除某个实体
	 * 
	 * @param entityClass
	 * @param id
	 */
	public static void deleteEntity(Class<?> entityClass, Object id) {
		EntityManagerFactory emf = Persistence
				.createEntityManagerFactory("zjusc");
		EntityManager em = emf.createEntityManager();

		// 开始事务
		em.getTransaction().begin();
		Object targetBean = em.find(entityClass, id);

		em.remove(targetBean);
		// 提交事务
		em.getTransaction().commit();

		em.close();
		emf.close();
	}

}
